
#include <bsp_key_config.h>

#ifndef KEY_NUM_MAX
#define KEY_NUM_MAX 		        1
#warning "BSP_KEY DON'T HAVE A UESER CONFIG,USEING DEFUALT CONFIG"
#endif // KEY_NUM_MAX
#ifndef KEY_PRESS_LEVEL
#define KEY_PRESS_LEVEL				0
#endif // KEY_PRESS_LEVEL
#ifndef KEY_JITTER_TICK
#define KEY_JITTER_TICK					0
#endif // KEY_JITTER_TIME
#ifndef KEY_LONG_PRESS_TICK
#define KEY_LONG_PRESS_TICK 		    100
#endif
#ifndef KEY_LONG_PRESS_REPEAT_TICK
#define KEY_LONG_PRESS_REPEAT_TICK 		100
#endif

#define KEY_RELEASE_LEVEL  (!KEY_PRESS_LEVEL)

uint8_t (*bsp_key_hal_read_pin_level_callbakc)(uint8_t key_num) = 0;
void (*bsp_key_free_callback)(uint8_t key_num) = 0;
void (*bsp_key_press_callback)(uint8_t key_num) = 0;
void (*bsp_key_release_callback)(uint8_t key_num) = 0;
void (*bsp_key_long_press_callback)(uint8_t key_num) = 0;
void (*bsp_key_long_press_repeat_callback)(uint8_t key_num) = 0;

typedef struct {
	uint16_t key_press_count;
	uint8_t key_last_pin_level;
} KEY_STRUCT;

static KEY_STRUCT KEYS[KEY_NUM_MAX];


static void key_struct_init(void)
{
    uint8_t i;
    for(i = 0; i < KEY_NUM_MAX; i++) {
        KEYS[i].key_press_count = 0;
        KEYS[i].key_last_pin_level = KEY_RELEASE_LEVEL;
	}
}


//press 1; release 0
uint8_t bsp_key_read_press_release(uint8_t key_mun)
{
	if(bsp_key_hal_read_pin_level_callbakc != 0){
		return (bsp_key_hal_read_pin_level_callbakc(key_mun) == KEY_PRESS_LEVEL);
	}
	else{
		return 0;
	}
}

uint8_t bsp_key_all_release(void)
{
	uint8_t i;
	uint8_t ret = 1;
	if(bsp_key_hal_read_pin_level_callbakc != 0){
		for (i = 0; i < KEY_NUM_MAX; i++) {
			if(bsp_key_hal_read_pin_level_callbakc(i) != KEY_RELEASE_LEVEL){
				ret = 0;
				break;
			}
		}
	}
	return ret;
}


static uint8_t i;
static uint8_t temp_key_pin_level;
void bsp_key_scan_handler(void)
{
	for (i = 0; i < KEY_NUM_MAX; i++) {
		if(bsp_key_hal_read_pin_level_callbakc != 0){
			temp_key_pin_level = bsp_key_hal_read_pin_level_callbakc(i);
		}
		else{
			temp_key_pin_level = KEY_RELEASE_LEVEL;
		}
        if(KEYS[i].key_last_pin_level == KEY_RELEASE_LEVEL){
            if(temp_key_pin_level == KEY_RELEASE_LEVEL){
                KEYS[i].key_press_count = 0;
				if(bsp_key_free_callback != 0)
					bsp_key_free_callback(i);
            }
            else{
			  	if(KEYS[i].key_press_count == 0){
					if(bsp_key_press_callback != 0)
						bsp_key_press_callback(i);
				}
                KEYS[i].key_press_count++;
            }
        }
        else{
            if(temp_key_pin_level == KEY_RELEASE_LEVEL){
#if (KEY_JITTER_TICK > 0)
				if(KEYS[i].key_press_count >= KEY_JITTER_TICK){
#endif
					if(bsp_key_release_callback != 0)
						bsp_key_release_callback(i);
#if (KEY_JITTER_TICK > 0)
				}
#endif
                KEYS[i].key_press_count = 0;
            }
            else{
                KEYS[i].key_press_count++;
                if(KEYS[i].key_press_count == KEY_LONG_PRESS_TICK){
					if(bsp_key_long_press_callback != 0){
						bsp_key_long_press_callback(i);
					}
                }
				else if(KEYS[i].key_press_count >= KEY_LONG_PRESS_TICK + KEY_LONG_PRESS_REPEAT_TICK){
					if(bsp_key_long_press_repeat_callback != 0){
						bsp_key_long_press_repeat_callback(i);
					}
					KEYS[i].key_press_count = KEY_LONG_PRESS_TICK;
				}
            }
        }
        KEYS[i].key_last_pin_level = temp_key_pin_level;
	}
}


void bsp_key_init(void (*bsp_key_hal_init_callback_handler)(void),
				uint8_t (*bsp_key_hal_read_pin_level_callbakc_handler)(uint8_t key_num),
				void (*bsp_key_free_callback_handler)(uint8_t key_num),
				void (*bsp_key_press_callback_handler)(uint8_t key_num),
				void (*bsp_key_release_callback_handler)(uint8_t key_num),
				void (*bsp_key_long_press_callback_handler)(uint8_t key_num))
{
	bsp_key_hal_read_pin_level_callbakc = bsp_key_hal_read_pin_level_callbakc_handler;
	bsp_key_free_callback = bsp_key_free_callback_handler;
	bsp_key_press_callback = bsp_key_press_callback_handler;
	bsp_key_release_callback = bsp_key_release_callback_handler;
	bsp_key_long_press_callback = bsp_key_long_press_callback_handler;

    key_struct_init();
    if(bsp_key_hal_init_callback_handler != 0){
		bsp_key_hal_init_callback_handler();
    }
}

void bsp_key_long_press_repeat_callback_register(void (*bsp_key_long_press_repeat_callback_handler)(uint8_t key_num))
{
	bsp_key_long_press_repeat_callback = bsp_key_long_press_repeat_callback_handler;
}
